/* --- class with pointer mumber --- */
#ifndef __MYSTRING__
#define __MYSTRING__

#include <iostream>
using namespace std;

class String {
private:
    char* m_data;

public:
    // Big Three，三个特殊函数：拷贝构造、拷贝赋值、析构函数
    // class with pointer members必须有copy ctor拷贝构造 和 copy op=拷贝赋值
    // 如果一个函数在类的声明和定义中都有默认参数值，那么只能在其中之一给出默认值。而不能在类的声明和定义中同时给出默认值。3
    String(const char* cstr = 0); // 在声明中给出默认参数，默认指针指向0就是NULL
    String(const String& str); // 拷贝构造
    String& operator=(const String& str); // 拷贝赋值
    ~String();
    // inline 方法
    char* get_c_str() const { return m_data; }
};

#include <cstring>

// ctor 构造函数
inline String::String(const char* cstr) { // 在定义中省略默认参数值，建议在类的声明中给出默认参数值，而在类的定义中省略默认参数值
    cout << "String::String(const char* cstr = 0)" << endl;
    if (cstr) {
        m_data = new char[strlen(cstr) + 1];
        strcpy(m_data, cstr);
    } else { // 未指定初值
        m_data = new char[1];
        *m_data = '\0';
    }
}

// dtor 析构函数，delete new的内存
inline String::~String() {
    cout << "String::~String()" << endl;
    delete[] m_data;
    m_data = nullptr;
}

// 不是local就可以用reference String&
inline String& String::operator=(const String& str) {
    cout << "String& String::operator=(const String& str)" << endl;
    // self assignment检测自我赋值，如果不检测，直接delete会将str也delete
    if (this == &str) {
        return *this;
    }
    delete[] m_data;
    m_data = new char[strlen(str.m_data) + 1];
    strcpy(m_data, str.m_data);
    return *this;
}

inline String::String(const String& str) {
    cout << "String::String(const String& str)" << endl;
    m_data = new char[strlen(str.m_data) + 1];
    strcpy(m_data, str.m_data);
}

ostream& operator<<(ostream& os, const String& str) {
    os << str.get_c_str();
    return os;
}

#endif